/*
 * table_CodeScope.c
 *
 *  Created on: 2012/03/30
 *      Author: guanxiaoying
 */
#include "../../parser/coredef.h"
typedef struct _CODESCOPE{
	AST fileindex;
	S4  startLine;
	S4  endLine;
	U2  startOffset;
	U2  endOffset;
	RBTREE rbtree;
}CODESCOPE, *PCODESCOPE;
#define TableSize  (sizeof(CODESCOPE))
#define TableType  PCODESCOPE
#define stTable stCodeScpManager.memoryBlocks
#define maxTable stCodeScpManager.maxRecordNum
#define  maxNumPerBlk  (stCodeScpManager.astMaxNum_Block)


/* get the object */
static AST gblRoot = 0;
static TABLEMANAGER stCodeScpManager = {
//		U4                  usIdx;
		0,
//		PSZ				    con_pszName;    constant
		__FILE__,
//		U2					con_usSize;		constant
		TableSize,
//		U2					block_num;	縲��縲��縲��縲�eset clear  髫帙�隕�
		0,
//		S4					astMaxNum_Block;     �大屓險ｭ螳壹�縺ｿ
		0,
//		S4					astTabNum_LastPage; 縲��縲��Reset clear  髫帙�隕�
		0,
//		S4					astMaxNum_LastPage;     Reset clear  髫帙�隕�
		0,
//		U4					ulMaxByte;	縲��縲��縲��縲��縲��繧ｯ繝ｪ繧｢縺励↑縺�
		0,
//		U4					con_minPageSize;縲��縲��縲��縲��縲��constant
		0
};

static VOID resetListener( U4  procid, U2 index )
{
	if( procid == stCodeScpManager.u4Idx )
	{
		if( index > 0 && index < MAX_VOLUMN_OF_TABLE )
		{
			stTable[ index-1] = NULL;
		}
	}
}
static TableType core_getTable( AST index )
{
	TableType temp = (TableType)Check_Com( &stCodeScpManager, resetListener,  index );
	if( temp != NULL ){
		if( temp != NULL ){ return &temp[index%maxNumPerBlk]; } return NULL;
	}
	return NULL;
}
static BOOL ClearTable( VOID )
{
	gblRoot = 0;
	return Clear_Com( &stCodeScpManager );
}
static BOOL ResetTable( VOID )
{
	gblRoot = 0;
	return Reset_Com( &stCodeScpManager );
}
static BOOL AllocTable( AST astReqArg )
{
	return AllocTable_Com( &stCodeScpManager, astReqArg, resetListener );
}
/**************************************************************************
* 髢｢ 謨ｰ 蜷�: copyTable
* 讖�   閭ｽ : 蜷後§繝��繝悶Ν縺ｮ陦後�繝悶Ο繝�け繧堤ｧｻ蜍輔☆繧�
* 蠑�縺�謨ｰ ��
* 縲��縲��縲��縲�stOrg :繧ｳ繝斐�蜈��髢句ｧ玖｡後�騾｣逡ｪ
* 		縲�stDst�壹�繧ｳ繝斐�蜈医�髢句ｧ玖｡後�騾｣逡ｪ
*         astlenth: 繝悶Ο繝�け荳ｭ縺ｮ陦後�謨ｰ
* 謌ｻ 繧�蛟､ : 謌仙粥縺吶ｋ蝣ｴ蜷医�1縲ょ､ｱ謨励☆繧句�蜷医�0
* 隧ｳ邏ｰ蜀�ｮｹ :  繝｡繝｢繝ｪ遘ｻ蜍�
************************************************************************/
static BOOL copyTable( AST  astOrg,  AST  astDst,  AST astLenth )
{
	return Copy_Com( &stCodeScpManager, resetListener, astOrg, astDst, astLenth );
}

static AST getMaxLineNum( VOID )
{
	return maxTable;
}

//ACCESS_PROCESS access;
//ACCESS_U2_FIELD startOffset;
static U2 getStartOffset( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->startOffset;
}
static U2 setStartOffset( AST index, U2 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->startOffset = value;
}
//ACCESS_U2_FIELD endOffset;
static U2 getEndOffset( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->endOffset;
}
static U2 setEndOffset( AST index, U2 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->endOffset = value;
}
//ACCESS_S4_FIELD startLine;
static S4 getStartLine( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->startLine;
}
static S4 setStartLine( AST index, S4 idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->startLine = idx;
}
//ACCESS_S4_FIELD endLine;
static S4 getEndLine( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->endLine;
}
static S4 setEndLine( AST index, S4 idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->endLine = idx;
}

//ACCESS_IDX_FIELD fileindex;
static AST getFileIndex( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->fileindex;
}
static AST setFileIndex( AST index, AST idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->fileindex = idx;
}
static AST getLeft( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astLeftChild;
}
static AST setLeft( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astLeftChild = value;
}
static AST getRight( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astRightChild;
}
static AST setRight( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astRightChild = value;
}
static AST getParent( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astParent;
}
static AST setParent( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astParent = value;
}
static U2 getColor( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.lColor;
}
static U2 setColor( AST index, U2 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.lColor = value;
}
//ACCESS_IDX_FIELD
static AST getIndex( AST index )
{
	return index;
}
static ACCESS_RBTREE stAccessRbtree =
{
		AllocTable,
		getMaxLineNum,
		getIndex,
		{
				getLeft,
				setLeft
		},
		{
				getRight,
				setRight
		},
		{
				getParent,
				setParent
		},
		{
				getColor,
				setColor
		}
};
static S4 cmpCodeScope( AST index, VOID* data )
{
	CODESCOPE_CMP * input =(CODESCOPE_CMP *) data;
	AST fileindex = stCoreCodeScpAccess.fileindex.get( index );
	AST startLine = stCoreCodeScpAccess.startLine.get( index );
	AST endLine = stCoreCodeScpAccess.endLine.get( index );
	U2  u2_Offset_Start = stCoreCodeScpAccess.startOffset.get( index );
	U2  u2_Offset_End = stCoreCodeScpAccess.endOffset.get( index );
	if( input == NULL )
	{
		return RBT_FOUND;
	}
	if( index == 0 )
	{
		return RBT_LESS;
	}
	if( startLine == 0 || endLine == 0 )
	{
		return RBT_MEMERROR;
	}
	if( input->fileindex < fileindex )
	{
		return RBT_LESS;
	}
	if( input->fileindex > fileindex )
	{
		return RBT_LARGER;
	}
	if( input->beginLine < startLine )
	{
		return RBT_LESS;
	}
	if( input->beginLine > startLine )
	{
		return RBT_LARGER;
	}
	if( input->endLine < endLine )
	{
		return RBT_LESS;
	}
	if( input->endLine > endLine )
	{
		return RBT_LARGER;
	}
	if( input->offset_begin < u2_Offset_Start )
	{
		return RBT_LESS;
	}
	if( input->offset_begin > u2_Offset_Start )
	{
		return RBT_LARGER;
	}
	if( input->offset_end < u2_Offset_End )
	{
		return RBT_LESS;
	}
	if( input->offset_end > u2_Offset_End )
	{
		return RBT_LARGER;
	}
	return RBT_FOUND;
}

static AST getCodeScope( CODESCOPE_CMP * input )
{
	AST astNewNode = 0;
	AST astParent = 0;
	S4 nCmpResult = 0;
	if( input == NULL )
	{
		return 0;
	}
	if( gblRoot > 0 )
	{
		nCmpResult = FindData( &stAccessRbtree, gblRoot , &input ,&astParent, cmpCodeScope );
		if( nCmpResult == 0 )
		{
			return astParent;
		}
	}
	else
	{
		astParent = 0;
		nCmpResult = 1;
	}
	if( FALSE == InsertData( &stAccessRbtree, nCmpResult, astParent, &gblRoot, &astNewNode ))
	{
		return 0;
	}
	if( astNewNode > 0 )
	{
		setFileIndex( astNewNode, input->fileindex );
		setStartOffset( astNewNode, input->offset_begin );
		setEndOffset( astNewNode, input->offset_end );
		setStartLine( astNewNode, input->beginLine );
		setEndLine( astNewNode, input->endLine );
	}
	return astNewNode;
}
static AST mergeCodeScope( AST scp1, AST scp2 )
{
	CODESCOPE_CMP input1, input2;

	if( getFileIndex( scp1 ) != getFileIndex( scp2 ))
	{
		return 0;
	}
	input1.fileindex = getFileIndex(scp1);
	input1.beginLine = getStartLine(scp1);
	input1.endLine = getEndLine(scp1);
	input1.offset_begin = getStartOffset( scp1 );
	input1.offset_end = getEndOffset( scp1 );
	input2.fileindex = getFileIndex(scp2);
	input2.beginLine = getStartLine(scp2);
	input2.endLine = getEndLine(scp2);
	input2.offset_begin = getStartOffset( scp2 );
	input2.offset_end = getEndOffset( scp2 );

	if( input1.beginLine > input2.beginLine )
	{
		input1.beginLine = input2.beginLine;
		input1.offset_begin = input2.offset_begin;
	}else if ( input1.beginLine == input2.beginLine )
	{
		if( input1.offset_begin > input2.offset_begin )
		{
			input1.offset_begin = input2.offset_begin;
		}
	}
	if( input1.endLine < input2.endLine )
	{
		input1.endLine = input2.endLine;
		input1.offset_end = input2.offset_end;
	}else if ( input1.endLine == input2.endLine )
	{
		if( input1.offset_end < input2.offset_end )
		{
			input1.offset_end = input2.offset_end;
		}
	}
	return getCodeScope( &input1 );
}

const CODESCOPE_ACCESS stCoreCodeScpAccess = {
//		BOOL (*clear)( VOID );
		ClearTable,
//		BOOL (*reset)( VOID );
		ResetTable,
//		BOOL (*alloc)( AST );
		AllocTable,
//		BOOL (*copy)( AST, AST, AST );
		copyTable,
//		AST  (*getMax)( VOID );
		getMaxLineNum,
//		AST  (*mergeCodeScp)( AST, AST );
		mergeCodeScope,
//		AST  (*getCodeScp)( CODESCOPE_CMP * );
		getCodeScope,
//		ACCESS_U2_FIELD startOffset;
		{
				getStartOffset,
				setStartOffset
		},
		//		ACCESS_U2_FIELD endOffset;

		{
				getEndOffset,
				setEndOffset
		},
		//		ACCESS_IDX_FIELD fileindex;

		{
				getFileIndex,
				setFileIndex
		},
//		ACCESS_IDX_FIELD startLine;
		{
				getStartLine,
				setStartLine
		},
//		ACCESS_IDX_FIELD endLine;
		{
				getEndLine,
				setEndLine
		}
};

/* end of file */
